package com.itheima.java.ai.langchin4j.service;

import com.itheima.java.ai.langchin4j.assistant.XiaozhiAgent;
import com.itheima.java.ai.langchin4j.enums.PromptScenario;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

/**
 * 小智AI代理服务类
 * 负责动态选择提示词模板并处理用户对话
 */
@Service
public class XiaozhiAgentService {
    
    private static final Logger logger = LoggerFactory.getLogger(XiaozhiAgentService.class);
    
    @Autowired
    private PromptTemplateService promptTemplateService;
    
    @Autowired
    private ChatLanguageModel openAiChatModel;
    
    @Autowired
    private ChatMemoryProvider chatMemoryProviderXiaozhi;
    
    @Autowired
    private ContentRetriever contentRetrieverXiaozhi;
    
    @Autowired
    private XiaozhiAgent defaultXiaozhiAgent;
    
    // 缓存不同场景的AI服务实例
    private final Map<PromptScenario, Object> scenarioAgentCache = new ConcurrentHashMap<>();
    
    /**
     * 智能对话处理
     * 根据用户消息内容自动选择最适合的提示词模板
     * 
     * @param memoryId 会话记忆ID
     * @param userMessage 用户消息
     * @return AI回复
     */
    public String chat(Long memoryId, String userMessage) {
        try {
            // 1. 智能识别场景
            PromptScenario scenario = PromptScenario.detectScenario(userMessage);
            logger.info("检测到场景: {} for message: {}", scenario.getDescription(), userMessage);
            
            // 2. 如果是默认场景，使用原有的代理
            if (scenario == PromptScenario.DEFAULT) {
                return defaultXiaozhiAgent.chat(memoryId, userMessage);
            }
            
            // 3. 获取场景特定的提示词
            String dynamicPrompt = promptTemplateService.generatePromptForScenario(scenario, userMessage);
            
            // 4. 创建或获取场景特定的AI代理
            Object scenarioAgent = getOrCreateScenarioAgent(scenario, dynamicPrompt);
            
            // 5. 调用场景特定的代理进行对话
            return invokeScenarioAgent(scenarioAgent, memoryId, userMessage);
            
        } catch (Exception e) {
            logger.error("处理对话时发生错误: {}", e.getMessage(), e);
            // 降级到默认代理
            return defaultXiaozhiAgent.chat(memoryId, userMessage);
        }
    }
    
    /**
     * 获取或创建场景特定的AI代理
     */
    private Object getOrCreateScenarioAgent(PromptScenario scenario, String systemPrompt) {
        return scenarioAgentCache.computeIfAbsent(scenario, key -> {
            try {
                // 创建场景特定的AI服务接口
                ScenarioAgent agent = AiServices.builder(ScenarioAgent.class)
                    .chatLanguageModel(openAiChatModel)
                    .chatMemoryProvider(chatMemoryProviderXiaozhi)
                    .contentRetriever(contentRetrieverXiaozhi)
                    .systemMessageProvider(memoryId -> systemPrompt)
                    .build();
                    
                logger.info("创建了新的场景代理: {}", scenario.getDescription());
                return agent;
                
            } catch (Exception e) {
                logger.error("创建场景代理失败: {}", e.getMessage(), e);
                return defaultXiaozhiAgent;
            }
        });
    }
    
    /**
     * 调用场景特定的代理
     */
    private String invokeScenarioAgent(Object agent, Long memoryId, String userMessage) {
        try {
            if (agent instanceof ScenarioAgent) {
                return ((ScenarioAgent) agent).chat(memoryId, userMessage);
            } else {
                // 降级到默认代理
                return defaultXiaozhiAgent.chat(memoryId, userMessage);
            }
        } catch (Exception e) {
            logger.error("调用场景代理失败: {}", e.getMessage(), e);
            // 降级到默认代理
            return defaultXiaozhiAgent.chat(memoryId, userMessage);
        }
    }
    
    /**
     * 清除场景代理缓存
     * 用于重新加载提示词模板后刷新代理
     */
    public void clearScenarioAgentCache() {
        scenarioAgentCache.clear();
        logger.info("已清除场景代理缓存");
    }
    
    /**
     * 获取当前缓存的场景代理数量
     */
    public int getCachedAgentCount() {
        return scenarioAgentCache.size();
    }
    
    /**
     * 场景特定的AI代理接口
     */
    public interface ScenarioAgent {
        String chat(@MemoryId Long memoryId, @UserMessage String userMessage);
    }
    
    /**
     * 手动指定场景进行对话
     * 用于测试或特殊需求
     * 
     * @param memoryId 会话记忆ID
     * @param userMessage 用户消息
     * @param scenario 指定的场景
     * @return AI回复
     */
    public String chatWithScenario(Long memoryId, String userMessage, PromptScenario scenario) {
        try {
            logger.info("手动指定场景: {} for message: {}", scenario.getDescription(), userMessage);
            
            if (scenario == PromptScenario.DEFAULT) {
                return defaultXiaozhiAgent.chat(memoryId, userMessage);
            }
            
            String dynamicPrompt = promptTemplateService.generatePromptForScenario(scenario, userMessage);
            Object scenarioAgent = getOrCreateScenarioAgent(scenario, dynamicPrompt);
            
            return invokeScenarioAgent(scenarioAgent, memoryId, userMessage);
            
        } catch (Exception e) {
            logger.error("手动指定场景对话时发生错误: {}", e.getMessage(), e);
            return defaultXiaozhiAgent.chat(memoryId, userMessage);
        }
    }
    
    /**
     * 获取可用的场景列表
     */
    public PromptScenario[] getAvailableScenarios() {
        return PromptScenario.values();
    }
}